﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace Aliyeye.Car.Net.UI.Controls
{
    public partial class AnimationOnPaint : Control
    {
        Image loadingIndicator = null;

        private delegate int TUpdateImage(int currentFrame);
        private TUpdateImage DUpdateAnimationImage;
        EventWaitHandle drawingWait = new EventWaitHandle(false, EventResetMode.AutoReset);
        int frameCount = 0;
        int currentFrame = 0;
        bool quiting = false;


        public AnimationOnPaint()
        {
            this.SetStyle(ControlStyles.SupportsTransparentBackColor |
                ControlStyles.DoubleBuffer | ControlStyles.UserPaint |
                ControlStyles.AllPaintingInWmPaint, true);

            //this.SetStyle(ControlStyles.SupportsTransparentBackColor |
            //    ControlStyles.Opaque, true);

            this.UpdateStyles();

            this.BackColor = Color.Transparent;

            DUpdateAnimationImage += new TUpdateImage(this.UpdateAnimationImage);

            loadingIndicator = Properties.Resources.indicator_spinning_3;

            frameCount = loadingIndicator.GetFrameCount(System.Drawing.Imaging.FrameDimension.Time);

            this.Width = loadingIndicator.Width;
            this.Height = loadingIndicator.Height;
            drawingWait = new EventWaitHandle(false, EventResetMode.AutoReset);

            InitializeComponent();
        }
        ~AnimationOnPaint()
        {
            quiting = true;
        }

        protected override void OnPaint(PaintEventArgs pe)
        {
            Graphics g = pe.Graphics;

            if (loadingIndicator != null)
            {
                g.DrawImageUnscaled(loadingIndicator, 0 , 0);
            }

            base.OnPaint(pe);

            drawingWait.Set();
        }


        public void StartAnimation()
        {
            if (!ImageAnimator.CanAnimate(loadingIndicator))
            {
                return;
            }

            quiting = false;

            //ImageAnimator.Animate(loadingIndicator, new EventHandler(this.HandleAnimated));
            ThreadPool.QueueUserWorkItem(delegate(object state)
            {
                while (true && !quiting)
                {
                    
                    HandleAnimated(ref currentFrame);
                    drawingWait.WaitOne();
                    Thread.Sleep(100);
                }
            });
        }

        public void StopAnimatinon()
        {
            if (!ImageAnimator.CanAnimate(loadingIndicator))
            {
                return;
            }

            quiting = true;
            // imageanimator sucks, it incorrectly skipped frames, wasted me all day long.
            //ImageAnimator.StopAnimate(loadingIndicator, new EventHandler(this.HandleAnimated));
        }

        private void HandleAnimated(ref int currentFrame)
        {
            try
            {
                currentFrame = (int)this.Invoke(this.DUpdateAnimationImage, currentFrame);
                
            }
            catch (Exception)
            {
            }
            
        }

        private int UpdateAnimationImage(int currentFrame)
        {
            loadingIndicator.SelectActiveFrame(System.Drawing.Imaging.FrameDimension.Time,
                    currentFrame);
            currentFrame++;
            this.Invalidate();
            if (currentFrame >= frameCount)
            {
                currentFrame = 0;
            }
            return currentFrame;
            //drawingWait.WaitOne(10000);
            //drawingWait.Reset();
            //ImageAnimator.UpdateFrames(loadingIndicator);
        }
    }

}
